var elements = {
    gameId: null,
    ajaxCount: null,
    scores: new Array(),
    scoreTotal: null,
    scoreFinal: null,
    load: function() {
        for (var i = 0; i < 3; i++) {
            classification.cells = document.getElementById("classCell" + i);
            multiplier.cells[i] = document.getElementById("multiplierCell" + i);
            attempt.cells[i] = document.getElementById("valueCell" + i);

            classification.inputs[i] = document.forms[0]["attempt[" + i + "].classification"];
            multiplier.inputs[i] = document.forms[0]["attempt[" + i + "].multiplier"];
            attempt.inputs[i] = document.getElementById("attempt[" + i + "].value");
            attempt.texts[i] = document.getElementById("valueText" + i);

            this.scores[i] = document.getElementById("score" + i);
        }

        this.gameId = document.getElementById("hidden-id");
        this.ajaxCount = document.getElementById("numAjaxCalls");
        this.scoreTotal = document.getElementById("scoreTotal");
        this.scoreFinal = document.getElementById("scoreFinal");
    }
};

var numAjaxCalls = false;
var hasBeenSubmitted = false;

var classification = {
    cells: new Array(),
    inputs: new Array(),
    setByUser: [false, false, false],
    beenSetOnce: false,
    change: function(index) {
        this.setByUser[index] = true;

        var cls = this.get(index);
        if (!this.beenSetOnce) {
            this.beenSetOnce = true;
            for (var i = 0; i < 3; i++)
                if (i != index)
                    this.set(i, cls);
        } else {
            for (var j = index + 1; j < 3; j++)
                if (!this.setByUser[j])
                    this.set(j, cls);
        }
        calculateScore();
    },
    get: function(index) {
        var radios = this.inputs[index];
        var value = null;
        for (var i = 0; i < radios.length; i++)
            if (radios[i].checked)
                value = Number(radios[i].value);
        return value;
    },
    isValid: function(index) {
        return (this.get(index) != null);
    },
    set: function(index, value) {
        var radios = this.inputs[index];
        for (var i = 0; i < radios.length; i++)
            if (radios[i].value == value)
                radios[i].checked = true;
    }
};

var multiplier = {
    cells: new Array(),
    inputs: new Array(),
    change: function(index) {
        var mult = this.get(index);
        if (mult == -1 && attempt.get(index) >= 0)
            attempt.set(index, "-5");
        else if (mult == 0)
            attempt.set(index, "0");
        attempt.updateDisplay(index);
        calculateScore();
    },
    get: function(index) {
        var radios = this.inputs[index];
        var value = null;
        for (var i = 0; i < radios.length; i++)
            if (radios[i].checked)
                value = Number(radios[i].value);
        return value;
    },
    isValid: function(index) {
        return (this.get(index) != null);
    },
    set: function(index, value) {
        var radios = this.inputs[index];
        for (var i = 0; i < radios.length; i++)
            if (radios[i].value == value)
                radios[i].checked = true;
    }
};

var attempt = {
    cells: new Array(),
    inputs: new Array(),
    texts: new Array(),
    change: function(index) {
        var value = this.get(index);
        if (value != null) {
            var mult = multiplier.get(index);
            if (value < 0 && mult != -1) {
                multiplier.set(index, -1);
            } else if (value == 0 ) {
                multiplier.set(index, 0);
            } else if (value == 50) {
                multiplier.set(index, 2);
                this.set(index, 25);
            } else if (value > 0 && mult < 1) {
                multiplier.set(index, 1);
            }
        }
        this.updateDisplay(index);
        calculateScore();
    },
    get: function(index) {
        var value = this.inputs[index].value;
        if (value != "" && isFinite(value))
            return Number(value);
        return null;
    },
    isValid: function(index) {
        var val = this.get(index);
        var mult = multiplier.get(index);
        if (val == null || mult == null)
            return false;

        if (val != Math.floor(val))
            return false;

        switch (mult) {
        case -1:
            return (val == -1 || val == -5 || val == -10 || val == -20);
        case 0:
            return (val == 0);
        default:
            return (1 <= val && val <= 20) || (val == 25 && mult != 3);
        }
    },
    set: function(index, value) {
        this.inputs[index].value = value;
    },
    updateDisplay: function(index) {
        this.inputs[index].className = this.isValid(index) ? "" : "error";

        var text = "";
        if (multiplier.get(index) == -1) {
            switch (this.get(index)) {
            case -1: text = "Bounce Out"; break;
            case -5: text = "Small"; break;
            case -10: text = "Large"; break;
            case -20: text = "Permanent"; break;
            default: text = "";
            }
        }
        this.texts[index].innerHTML = text;
    }
};

function calculateScore() {
    var data = 'remote=true&id=' + elements.gameId.value;
    for (var i = 0; i < 3; i++) {
        var cls = classification.get(i);
        var mult = multiplier.get(i);
        if (cls == null || mult == null)
            return;
        var val = ( attempt.isValid(i) ? attempt.get(i) : 0);

        data += '&attempt[' + i + '].classification=' + cls;
        data += '&attempt[' + i + '].multiplier=' + mult;
        data += '&attempt[' + i + '].value=' + val;
    }

    var xmlHttpReq = new XMLHttpRequest();
    xmlHttpReq.open('POST', '/DART/gamePlay/calculate', true);
    xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttpReq.onreadystatechange = function() {
        if (xmlHttpReq.readyState == 4) {
            displayScores(xmlHttpReq.responseText);
        }
    };
    numAjaxCalls++;
    elements.ajaxCount.innerHTML = numAjaxCalls;
    xmlHttpReq.send(data);
}

function displayScores(scoreData) {
    numAjaxCalls--;
    elements.ajaxCount.innerHTML = numAjaxCalls;
    var scores = scoreData.split('|');
    for (var i = 0; i < 3; i++)
        elements.scores[i].innerHTML = scores[i];

    elements.scoreTotal.innerHTML = scores[3];
    elements.scoreFinal.innerHTML = scores[4];
}

function trySubmit() {
    if (hasBeenSubmitted) {
        if (! confirm("The data has been submitted once, submit again?"))
            return false;
    }

    try {
        var test = true;
        for (var i = 0; i < 3; i ++) {
            test &= classification.isValid(i);
            test &= multiplier.isValid(i);
            test &= attempt.isValid(i);
        }

        if (test)
            hasBeenSubmitted = true;

        return Boolean(test);
    } catch(e) {
        alert(e);
        return false;
    }
}
